package com.ybear.ybutils.utils.toast;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;

import com.ybear.ybutils.utils.R;
import com.ybear.ybutils.utils.handler.Handler;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;

public class ToastX {
    @IntDef({ LENGTH_SHORT, LENGTH_LONG })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Duration {}

    @RequiresApi(android.os.Build.VERSION_CODES.R)
    public abstract static class Callback extends Toast.Callback { }

    public static final int LENGTH_SHORT = Toast.LENGTH_SHORT;
    public static final int LENGTH_LONG = Toast.LENGTH_LONG;

    private final WeakReference<Context> mWRContext;
    private final Handler mHandler;
    private final Toast mToast;
    private final Build mBuild;

    private TextView tvToastView;

    public ToastX(@NonNull Context context, Handler handler, @NonNull Build build) {
        mWRContext = new WeakReference<>( context );
        mHandler = handler;
        mToast = new Toast( context );
        mBuild = build;
        setGravity( build.getGravity() );
        setMargin( build.getMargin()[ 0 ], build.getMargin()[ 1 ] );
    }

    /**
     * 显示Toast
     * @return  处理结果
     */
    public boolean show() { return post( mToast::show ); }

    /**
     * 取消Toast
     * @return  处理结果
     */
    public boolean cancel() { return post( mToast::cancel ); }

    private boolean post(@NonNull Runnable r) {
        try {
            //handler展示
            if( mHandler != null ) return mHandler.post( r );
            //正常展示
            r.run();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public ToastX setText(@StringRes int resId) {
        if( tvToastView == null ) mToast.setView( tvToastView = createToastView() );
        if( tvToastView != null ) tvToastView.setText( resId );
        return this;
    }

    public ToastX setText(@Nullable CharSequence s) {
        if( tvToastView == null ) mToast.setView( tvToastView = createToastView() );
        if( tvToastView != null && s != null ) tvToastView.setText( s );
        return this;
    }

    public ToastX setMargin(float horizontalMargin, float verticalMargin) {
        mToast.setMargin( horizontalMargin, verticalMargin );
        return this;
    }
    public float getHorizontalMargin() { return mToast.getHorizontalMargin(); }
    public float getVerticalMargin() { return mToast.getVerticalMargin(); }

    public ToastX setGravity(int gravity, int xOffset, int yOffset) {
        mToast.setGravity( gravity, xOffset, yOffset );
        return this;
    }

    public ToastX setGravity(int gravity) {
        return setGravity( gravity, mBuild.getXOffset(), mBuild.getYOffset() );
    }
    public int getGravity() { return mToast.getDuration(); }

    public int getXOffset() { return mToast.getXOffset(); }

    public int getYOffset() { return mToast.getYOffset(); }

    public ToastX setDuration(@Duration int duration) {
        mToast.setDuration( duration );
        return this;
    }
    public int getDuration() { return mToast.getDuration(); }

    @RequiresApi(android.os.Build.VERSION_CODES.R)
    public void addCallback(ToastX.Callback callback) {
        mToast.addCallback( callback );
    }

    @RequiresApi(android.os.Build.VERSION_CODES.R)
    public void removeCallback(ToastX.Callback callback) {
        mToast.removeCallback( callback );
    }

    public View getView() { return mToast.getView(); }

    /**
     * 创建Toast文本
     * @return  TextView
     */
    private TextView createToastView() {
        Context context = mWRContext.get();
        if( context == null ) return null;

        int[] p = mBuild.getPadding();
        ToastTextView v = new ToastTextView( context );

        int[] comDraws = mBuild.getCompoundDrawables();
        //小图标
        v.setCompoundDrawablesRelativeWithIntrinsicBounds(
                comDraws[ 0 ], comDraws[ 1 ], comDraws[ 2 ], comDraws[ 3 ]
        );
        //小图标间距
        v.setCompoundDrawablePadding( mBuild.getCompoundDrawablesPadding() );
        //字体大小
        v.setTextSize( mBuild.getTextSize() );
        //字体颜色
        v.setTextColor( mBuild.getTextColor() );
        //字体样式
        if( mBuild.getTypeface() != null ) v.setTypeface( mBuild.getTypeface() );
        //间距
        v.setPaddingRelative( p[0], p[1], p[2], p[3] );
        //背景
        if( mBuild.getBackground() != null ) {
            Drawable drawable = mBuild.getBackground();
            //Drawable背景
            v.setBackground( drawable );
        } else {
            if( mBuild.getBackgroundColor() != -1 ) {
                //颜色背景
                v.setBackgroundColor( mBuild.getBackgroundColor() );
            }else {
                int res = mBuild.getBackgroundResource();
                //资源id背景
                v.setBackgroundResource( res == -1 ? R.color.colorF6 : res );
            }
        }
        //显示位置
        v.setGravity( mBuild.getGravity() );

        /* Shape */
        float[] radius = mBuild.getRadius();
        //圆角大小
        if( radius != null ) {
            v.setRadius( radius[ 0 ], radius[ 1 ], radius[ 2 ], radius[ 3 ] );
        }
        //边框大小
        v.setBorderSize( mBuild.getBorderSize() );
        //边框颜色
        v.setBorderColor( mBuild.getBorderColor() );
        //阴影圆角大小
        v.setShadowRadius( mBuild.getShadowRadius() );
        //阴影圆角颜色
        v.setShadowColor( mBuild.getShadowColor() );
        //阴影偏移X
        v.setShadowOffsetX( mBuild.getShadowOffsetX() );
        //阴影偏移Y
        v.setShadowOffsetY( mBuild.getShadowOffsetY() );
        return v;
    }
}